//
//  QRViewController.m
//  ZLZKBaseUtils
//
//  Created by sxh on 2020/11/30.
//

#import "QRViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "TipsHud.h"
#import "macro.h"

@interface QRViewController ()
<AVCaptureMetadataOutputObjectsDelegate, AVCaptureVideoDataOutputSampleBufferDelegate,UINavigationControllerDelegate, UIImagePickerControllerDelegate>{
    NSTimer *_timer;
 BOOL upOrDown;
 int num;
}
@property (strong, nonatomic) AVCaptureDevice * device;
@property (strong, nonatomic) AVCaptureDeviceInput * input;
@property (strong, nonatomic) AVCaptureMetadataOutput * output;
@property (nonatomic, strong) AVCaptureVideoDataOutput *videoDataOutput;
@property (strong, nonatomic) AVCaptureSession *session;
@property (strong, nonatomic) AVCaptureVideoPreviewLayer * preview;
@property (strong, nonatomic) UIImageView *imageView;
@property (retain, nonatomic) UIImageView *line;
@property (nonatomic, strong) NSString     *identifier;
@property (nonatomic, strong) UIButton *lightBtn;
@property (nonatomic, strong) UIButton *flashlightBtn;
@property (nonatomic, strong) UIButton *imageBtn;
@property (nonatomic, assign) BOOL isSelectedFlashlightBtn;
@property (nonatomic, strong) UIImagePickerController *currentVC;

@end

@implementation QRViewController

- (AVCaptureDevice *)device{
    if (_device == nil) {
        _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    }
    return _device;
}
 
- (AVCaptureDeviceInput *)input{
    if (_input == nil) {
        _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
    }
    return _input;
}
 
- (AVCaptureMetadataOutput *)output{
    
    if (_output == nil) {
        _output = [[AVCaptureMetadataOutput alloc]init];
        [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
        //限制扫描区域(上下左右)
        [_output setRectOfInterest:[self rectOfInterestByScanViewRect:_imageView.frame]];
    }
    return _output;
}
 
- (CGRect)rectOfInterestByScanViewRect:(CGRect)rect {
    CGFloat width = CGRectGetWidth(self.view.frame);
    CGFloat height = CGRectGetHeight(self.view.frame);
    CGFloat x = (height - CGRectGetHeight(rect)) / 2 / height;
    CGFloat y = (width - CGRectGetWidth(rect)) / 2 / width;
    CGFloat w = CGRectGetHeight(rect) / height;
    CGFloat h = CGRectGetWidth(rect) / width;
    return CGRectMake(x, y, w, h);
}
 
- (AVCaptureSession *)session{
    if (_session == nil) {
        //session
        _session = [[AVCaptureSession alloc]init];
        [_session setSessionPreset:AVCaptureSessionPresetHigh];
        if ([_session canAddInput:self.input]) {
            [_session addInput:self.input];
        }
        if ([_session canAddOutput:self.output]) {
            [_session addOutput:self.output];
        }
    }
    return _session;
}
 
- (AVCaptureSession *)preview{
    if (_preview == nil) {
        _preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
    }
    return (AVCaptureSession *)_preview;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"扫码";
    
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    [self initView];
    
    self.navigationController.navigationBarHidden = NO;
    UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_back" inBundle:[self getBundle] compatibleWithTraitCollection:nil] style:UIBarButtonItemStylePlain target:self action:@selector(goBack)];
    self.navigationItem.leftBarButtonItem = backItem;
}

- (void)goBack {
    [self.navigationController popViewControllerAnimated:YES];
}
 
- (void)initView {

    for (UIView *sub in self.view.subviews) {
        [sub removeFromSuperview];
    }
    [self addTimer];
    [self addImageView];
    [self scanSetup];
    [self.view addSubview:self.lightBtn];
    [self.view addSubview:self.imageBtn];
    
}
 
//添加扫描框
- (void)addImageView{
    

    _imageView = [[UIImageView alloc]initWithFrame:CGRectMake((kScreenWidth - (self.view.center.x + 30))/2, (kScreenHeight - (self.view.center.x + 30))/2, self.view.center.x + 30, self.view.center.x + 30)];
    //显示扫描框
    _imageView.image = [UIImage imageNamed:@"qrcode_border_new" inBundle:[self getBundle] compatibleWithTraitCollection:nil];
    [self.view addSubview:_imageView];
    _line = [[UIImageView alloc]initWithFrame:CGRectMake(CGRectGetMinX(_imageView.frame)+5, CGRectGetMinY(_imageView.frame)+5, CGRectGetWidth(_imageView.frame), 3)];
    _line.image = [UIImage imageNamed:@"qrcode_scan_line" inBundle:[self getBundle] compatibleWithTraitCollection:nil];
    [self.view addSubview:_line];
    
    UILabel * lable = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    [lable setText:@"将二维码放入框内，自动识别"];
    lable.textAlignment = NSTextAlignmentCenter;
    lable.textColor = [UIColor whiteColor];
    lable.font = [UIFont systemFontOfSize:14];
    lable.center = CGPointMake(_imageView.center.x , _imageView.center.y+ (self.view.center.x + 30)/2 + 30);
    [self.view addSubview:lable];
}
 
//初始化扫描配置
- (void)scanSetup{
    
    self.preview.frame = self.view.bounds;
    self.preview.videoGravity = AVLayerVideoGravityResize;
    [self.view.layer insertSublayer:self.preview atIndex:0];
    
    [self.output setMetadataObjectTypes:@[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeQRCode]];
    [self.session setSessionPreset:AVCaptureSessionPresetHigh];
    [self.session startRunning];
    
    UIButton *back = [[UIButton alloc] initWithFrame:CGRectMake(0, kStatusBarHeight, 80, 44)];
    [back setTitle:@"返回" forState:0];
    [back.titleLabel setTextColor:[UIColor whiteColor]];
    [back.titleLabel setTextAlignment:NSTextAlignmentLeft];
    [self.view addSubview:back];
    [back addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
    
}
 
- (void)viewDidDisappear:(BOOL)animated {
    [self.session stopRunning];
    [_timer setFireDate:[NSDate distantFuture]];
}

- (void)chooseImage {
    self.currentVC = [[UIImagePickerController alloc] init];
    self.currentVC.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
    self.currentVC.modalPresentationStyle = UIModalPresentationFullScreen;
    self.currentVC.delegate = self;
    [self presentViewController:self.currentVC animated:YES completion:nil];
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    if ([metadataObjects count] > 0) {
        AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects objectAtIndex:0];
        if ([metadataObject isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
            NSString *stringValue = [metadataObject stringValue];
            if (stringValue != nil) {
                [self.session stopRunning];
                
                [self handleResult:stringValue];
            }
        }
    }
    if (_scanBlock) {
        _scanBlock(nil, RecognitionFaield);
    }
}

- (void)handleResult:(NSString *)stringValue {
    if (_scanBlock) {
        _scanBlock(stringValue, RecognitionSuccess);
//        [self.navigationController popViewControllerAnimated:YES];
    }
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    // 这个方法会时时调用，但内存很稳定
    CFDictionaryRef metadataDict = CMCopyDictionaryOfAttachments(NULL,sampleBuffer, kCMAttachmentMode_ShouldPropagate);
    NSDictionary *metadata = [[NSMutableDictionary alloc] initWithDictionary:(__bridge NSDictionary*)metadataDict];
    CFRelease(metadataDict);
    NSDictionary *exifMetadata = [[metadata objectForKey:(NSString *)kCGImagePropertyExifDictionary] mutableCopy];
    float brightnessValue = [[exifMetadata objectForKey:(NSString *)kCGImagePropertyExifBrightnessValue] floatValue];
    NSLog(@"%f",brightnessValue);
   if (brightnessValue < - 1) {
        [self.view addSubview:self.lightBtn];
    } else {
        if (self.isSelectedFlashlightBtn == NO) {
            [self removeFlashlightBtn];
        }
    }
}

- (void)lightBtnAction:(UIButton *)button {
    if (button.selected == NO) {
      /** 打开手电筒 */
          AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
          NSError *error = nil;
          if ([captureDevice hasTorch]) {
              BOOL locked = [captureDevice lockForConfiguration:&error];
              if (locked) {
                  captureDevice.torchMode = AVCaptureTorchModeOn;
                  [captureDevice unlockForConfiguration];
              }
          }
          self.isSelectedFlashlightBtn = YES;
          button.selected = YES;
    } else {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)),                  dispatch_get_main_queue(), ^{
              AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
              if ([device hasTorch]) {
                    [device lockForConfiguration:nil];
                    [device setTorchMode: AVCaptureTorchModeOff];
                    [device unlockForConfiguration];
              }
                button.selected = NO;
                self.isSelectedFlashlightBtn = NO;
                self.flashlightBtn.selected = NO;
                [self.flashlightBtn removeFromSuperview];
        });

    }
}

- (void)removeFlashlightBtn {
    [self.flashlightBtn removeFromSuperview];
}
 
- (void)addTimer{
    _timer = [NSTimer scheduledTimerWithTimeInterval:0.008 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
}
//控制扫描线上下滚动
- (void)timerMethod{
    if (upOrDown == NO) {
        num ++;
        _line.frame = CGRectMake(CGRectGetMinX(_imageView.frame)+5, CGRectGetMinY(_imageView.frame)+5+num, CGRectGetWidth(_imageView.frame)-10, 3);
        if (num == (int)(CGRectGetHeight(_imageView.frame)-10)) {
            upOrDown = YES;
        }
    }
    else{
        num --;
        _line.frame = CGRectMake(CGRectGetMinX(_imageView.frame)+5, CGRectGetMinY(_imageView.frame)+5+num, CGRectGetWidth(_imageView.frame)-10, 3);
        if (num == 0) {
            upOrDown = NO;
        }
    }
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
    // 对选取照片的处理，如果选取的图片尺寸过大，则压缩选取图片，否则不作处理
    UIImage *image = [self LY_imageSizeWithScreenImage:[info objectForKey:@"UIImagePickerControllerOriginalImage"]];
    
    // CIDetector(CIDetector可用于人脸识别)进行图片解析，从而使我们可以便捷的从相册中获取到二维码
    // 声明一个 CIDetector，并设定识别类型 CIDetectorTypeQRCode
    CIDetector *detector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:@{CIDetectorAccuracy: CIDetectorAccuracyHigh}];
    
    // 取得识别结果
    NSArray *features = [detector featuresInImage:[CIImage imageWithCGImage:image.CGImage]];
    
    if (features.count == 0) {
        [[TipsHud sharedInstance] showTips:@"未识别图像"];
        [self.currentVC dismissViewControllerAnimated:YES completion:nil];
        return;
    } else {
        [self.currentVC dismissViewControllerAnimated:YES completion:^{
           CIQRCodeFeature *feature = [features lastObject];
           NSString *stringValue = feature.messageString;
           [self handleResult:stringValue];
        }];
    }
}

//暂定扫描
- (void)stopScan{
    [self.session stopRunning];
    [_timer setFireDate:[NSDate distantFuture]];
    _line.hidden = YES;
}
- (void)starScan{
    [self.session startRunning];
    [_timer setFireDate:[NSDate distantPast]];
    _line.hidden = NO;
}

- (NSString *)convert2JSONWithDictionary:(NSDictionary *)dic{
    NSError *err;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:&err];
    
    NSString *jsonString;
    if (!jsonData) {
        NSLog(@"%@",err);
    }else{
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSLog(@"%@",jsonString);
    return jsonString;
}

/// 返回一张不超过屏幕尺寸的 image
- (UIImage *)LY_imageSizeWithScreenImage:(UIImage *)image {
    CGFloat imageWidth = image.size.width;
    CGFloat imageHeight = image.size.height;
    CGFloat screenWidth = kScreenWidth;
    CGFloat screenHeight = kScreenHeight;
    
    if (imageWidth <= screenWidth && imageHeight <= screenHeight) {
        return image;
    }
    
    CGFloat max = MAX(imageWidth, imageHeight);
    CGFloat scale = max / (screenHeight * 2.0);
    
    CGSize size = CGSizeMake(imageWidth / scale, imageHeight / scale);
    UIGraphicsBeginImageContext(size);
    [image drawInRect:CGRectMake(0, 0, size.width, size.height)];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return newImage;
}

- (UIButton *)lightBtn {
    if (_lightBtn == nil) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(10, kScreenHeight - 200, 50, 50);
//        [button setTitle:@"开灯" forState:UIControlStateNormal];
//        [button setTitle:@"关灯" forState:UIControlStateSelected];
        [button setImage:[UIImage imageNamed:@"light_battery_un" inBundle:[self getBundle] compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"light_battery" inBundle:[self getBundle] compatibleWithTraitCollection:nil] forState:UIControlStateSelected];
        [button addTarget:self action:@selector(lightBtnAction:) forControlEvents:UIControlEventTouchUpInside];
        _lightBtn = button;
    }
    
    return _lightBtn;
}

- (UIButton *)flashlightBtn {
    if (_lightBtn == nil) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(10, kScreenHeight - 200, 50, 50);
        [button setTitle:@"关灯" forState:UIControlStateNormal];
        [button addTarget:self action:@selector(lightBtnAction:) forControlEvents:UIControlEventTouchUpInside];
        _flashlightBtn = button;
    }
    
    return _flashlightBtn;
}

- (UIButton *)imageBtn {
    if (_imageBtn == nil) {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(kScreenWidth - 60, kScreenHeight - 200, 50, 50);
//        [button setTitle:@"相册" forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"photo_square" inBundle:[self getBundle] compatibleWithTraitCollection:nil] forState:UIControlStateNormal];
        [button addTarget:self action:@selector(chooseImage) forControlEvents:UIControlEventTouchUpInside];
        _imageBtn = button;
    }
    
    return _imageBtn;
}

- (void)back
{
    _scanBlock(nil, RecognitionCancel);
}

- (NSBundle *)getBundle {
    
    NSString *mainStr = [[NSBundle mainBundle] bundlePath];
    
    NSString *moduleStr1 = [mainStr stringByAppendingPathComponent:@"ZLZKBaseUtils.bundle"];
    NSBundle *module1 = [NSBundle bundleWithPath:moduleStr1];
    
    NSString *moduleStr2 = [mainStr stringByAppendingPathComponent:@"Frameworks/ZLZKBaseUtils.framework/ZLZKBaseUtils.bundle"];
    NSBundle *module2 = [NSBundle bundleWithPath:moduleStr2];
    return module1 ?: module2;
}
@end
